<template>
    <div class="logic-flow">
        <a-card class="h-full">
            <div id="container" ref="containerRef"></div>
            <context-menu
                v-model:show="isShowMenu"
                :options="menuOpt"
            >
                <context-menu-item
                    v-for="i in menuList"
                    :key="i.key"
                    :label="i.label"
                    @click="()=>{
                        menuClick(i)
                    }"
                />
            </context-menu>
        </a-card>
        <approval-drawer ref="approvalDrawerRef"/>
        <condition-drawer ref="conditionDrawerRef"/>
        <copy-drawer ref="copyDrawerRef"/>
        <a-modal
            v-model:open="state.showVersionModal"
            title="历史版本选择"
            :width="400"
            @cancel="state.showVersionModal = false"
            @ok="handleChangeVersion"
        >
            <a-select style="width: 100%;" v-model:value="state.curVersion">
                <a-select-option v-for="i in state.versions" :key="i" :value="i.flowVersion" @click="()=>state.curVersionData = i">
                    <template v-if="i.isOld == 2 && i.enable == 1">
                        最新版本
                    </template>
                    <template v-else>第{{ i.flowVersion }}版本</template>
                </a-select-option>
            </a-select>
        </a-modal>
    </div>
</template>

<script setup lang="ts">
// 插件
import LogicFlow from "@logicflow/core";
import "@logicflow/core/lib/style/index.css";
import { Control, SelectionSelect, Menu, MiniMap, Highlight } from '@logicflow/extension';
import '@logicflow/core/es/index.css';
import '@logicflow/extension/es/index.css';

import { onMounted, onUnmounted, reactive, ref, useTemplateRef } from "vue";
import customGlobal from "./config/customGlobal";
import customNode from "./config/customNode";
import type { MenuType } from "@/views/dataview/pages/design/components/hooks/useContextMenu";
import { MenuEnum } from "@/enum";
import { useCreateNodes } from "./hooks";

import '@imengyu/vue3-context-menu/lib/vue3-context-menu.css'
import {ContextMenu,ContextMenuItem} from '@imengyu/vue3-context-menu'

import approvalDrawer from "./drawer/approvalDrawer.vue";
import conditionDrawer from "./drawer/conditionDrawer.vue";
import copyDrawer from "./drawer/copyDrawer.vue";

const { createStartNode, createEndNode, createApprovalNode, createConditionNode, createCopyNode } = useCreateNodes()
const containerRef = useTemplateRef("containerRef")
const approvalDrawerRef = useTemplateRef('approvalDrawerRef')
const conditionDrawerRef = useTemplateRef('conditionDrawerRef')
const copyDrawerRef = useTemplateRef('copyDrawerRef')

const lf = ref<LogicFlow>()
const selectionSelect = ref()
const isShowMenu = ref(false)

const state = reactive({
    showVersionModal:false,
    versions:[] as any[],
    curVersion:null,
    curVersionData:null
})

const menuOpt = ref({
    zIndex: 3,
    minWidth: 230,
    x: 500, //记录菜单位于窗口位置
    y: 200,
    pointX:0, //记录插入点位于画布位置
    pointY:0
})

const menuList: MenuType[] = [
    {
        label: '开始节点',
        key: MenuEnum.START,
        fn: () => createStartNode(lf.value as LogicFlow,menuOpt.value.pointX,menuOpt.value.pointY)
    },
    {
        label: '审批节点',
        key: MenuEnum.APPROVAL,
        fn: () => createApprovalNode(lf.value as LogicFlow,menuOpt.value.pointX,menuOpt.value.pointY)
    },
    {
        label: '条件节点',
        key: MenuEnum.CONDITION,
        fn: () => createConditionNode(lf.value as LogicFlow,menuOpt.value.pointX,menuOpt.value.pointY)
    },
    {
        label: '抄送节点',
        key: MenuEnum.COPY,
        fn: () => createCopyNode(lf.value as LogicFlow,menuOpt.value.pointX,menuOpt.value.pointY)
    },
    {
        label: '结束节点',
        key: MenuEnum.END,
        fn: () => createEndNode(lf.value as LogicFlow,menuOpt.value.pointX,menuOpt.value.pointY)
    },
    {
        label: '全选',
        key: MenuEnum.SELECT_ALL,
        fn: () => selectAll()
    },
    {
        label:"版本切换",
        key:"version",
        fn:()=>{state.showVersionModal = true}
    }
]

const menuClick = (item:any)=>{
    item.fn()
}

// 框选
function selectAll() {
    // 三秒之内可以全选，时间一过则关闭(画布拖拽会和全选的拖拽形成冲突只能开启一个)
    let timer: any = null
    selectionSelect.value.openSelectionSelect();

    timer = setTimeout(() => {
        selectionSelect.value.closeSelectionSelect();
        clearTimeout(timer)
    }, 3000)
}

const editNode = (node: any) => {
    const type = node.properties.prop
    switch(type){
        case MenuEnum.APPROVAL:
            approvalDrawerRef.value?.handleOpen(node,lf.value as LogicFlow)
            break;
        case MenuEnum.CONDITION:
            conditionDrawerRef.value?.handleOpen(node,lf.value as LogicFlow)
            break;
        case MenuEnum.COPY:
            copyDrawerRef.value?.handleOpen(node,lf.value as LogicFlow)
            break
        default:
            break
    }
}


const getLfData = ()=>{
    const data =  lf.value?.getGraphData()
    return data
}


const setLfData = (data:any)=>{
    lf.value?.render(data);
}

const setVersionListAndCurVersion = (data:any[],curVer:any)=>{
    state.versions = data || []
    state.curVersion = curVer
}

// 修改版本
const handleChangeVersion = ()=>{
    if(state.curVersionData){
        lf.value?.render(JSON.parse(state.curVersionData.flowContent));
    }
    console.log(state.curVersionData)
    state.showVersionModal = false
}

onMounted(() => {
    if (!containerRef.value) return
    lf.value = new LogicFlow({
        container: containerRef.value,
        grid: true,
        snapline: true,
        plugins: [Menu, Control, SelectionSelect, MiniMap, Highlight],
        pluginsOptions: {
            miniMap: {
                width: 200,
                height: 120,
                showEdge: true
            },
        }
    });
    lf.value.setTheme({
        polyline: {
            stroke: "#6a6b6c",
            strokeWidth: 2,
        },
        snapline: {
            stroke: '#1E90FF', // 对齐线颜色
            strokeWidth: 3, // 对齐线宽度
        },
    });
    lf.value.extension.menu.setMenuConfig({
        nodeMenu: [
            {
                text: '分享',
                callback() {
                    alert('分享成功！')
                },
            },
            {
                text: '属性',
                callback(node: any) {
                    console.log('属性', node);
                },
            },
            {
                text:"编辑",
                callback(node:any){
                    editNode(node)
                }
            },
            {
                text:"删除",
                callback(node:any){
                    lf.value?.deleteNode(node.id)
                }
            }
        ],
        graphMenu: [],
    })
    lf.value.register(customGlobal)
    lf.value.register(customNode)
    lf.value.render({});
    lf.value.translateCenter()
    
    lf.value.on('node:dbclick',(data)=>{
        console.log('节点双击',data.data);
        editNode(data.data)
    })
    lf.value.on('blank:contextmenu',(data)=>{
        console.log('画布右键',data);
        data.e.preventDefault();
        //显示组件菜单
        isShowMenu.value = true;
        menuOpt.value.x = data.e.clientX;
        menuOpt.value.y = data.e.clientY;
        menuOpt.value.pointX = data.position.canvasOverlayPosition.x;
        menuOpt.value.pointY = data.position.canvasOverlayPosition.y;
    })
    lf.value.on('blank:click',()=>{
        isShowMenu.value = false
    })
    // 开启框选
    selectionSelect.value = lf.value.extension.selectionSelect
    selectionSelect.value.setSelectionSense(true, true)
    // 高亮配置
    lf.value.extension.highlight.setEnable(true);
    lf.value.extension.highlight.setMode('path');
    // 开启小地图
    lf.value.extension.miniMap.show()
})

onUnmounted(()=>{
    lf.value.extension.miniMap.hide()
})


defineExpose({
    getLfData,
    setLfData,
    setVersionListAndCurVersion
})
</script>

<style lang='scss' scoped>
.logic-flow {
    height: 100%;
}

:deep(.ant-card-body) {
    height: 100%;
}

#container {
    width: 100%;
    height: 100%;
}
</style>